/**
 ******************************************************************************
 * @file    app_uart_sever.c
 * @author  ��Ӿ��
 * @date    2025/6/16
 * @version v1.0
 * @brief   UARTͨ��Э�����ʵ���ļ�
 *          ����Э����������������RGB�ƿ��Ƶȹ��ܵĶԽӡ�
 * @copyright Copyright (c) 2025
 * @note    ������ ��-20 ��Ŀ������HAL�⿪����
 ******************************************************************************
 */
// filepath: d:\STM32\Project\STM32F4\HAL\Demo1_key\APP\app_uart_sever.c

#include "app_uart_sever.h"
#include "app_rgb.h"
#include "mid_circular_buffer.h"
#include "bsp_uart_diver.h"
//#include "usart.h"

/**
 * @brief �����ṹ�壬�洢ϵͳ����
 */
Parameters_U g_parameters = {0}; // ȫ�ֲ�������

/**
 * @brief ����Э��ͷ������
 * @param g_garameters Э������ṹ��ָ��
 * @param send_dat     �������ݻ�����
 */
static void hand_Generate(Agreement_T *g_garameters, uint8_t *send_dat)
{
    send_dat[0] = 0xA5; send_dat[1] = 0x5A;// ��ͷ
    send_dat[2] = 0x31; send_dat[3] = 0x00;// �汾����Դ
    send_dat[4] = 0x00;// ����
    // ������
    send_dat[5] = g_garameters->agreement_u.agreement_t.cmd_group;
    // ����� | 0x10
    send_dat[6] = g_garameters->agreement_u.agreement_t.cmd_num|0x10; 
    send_dat[7] = 0x00;// �̶�
}

/**
 * @brief ��������У���
 * @param send_dat �������ݻ�����
 * @param len      ���ݳ���ָ��
 * @param start    У����ʼλ��
 */
static void Checksum_calculation(uint8_t *send_dat, uint16_t *len, uint8_t start)
{
    uint8_t i;
    uint16_t temp = 0;
    for (i = 0; i < 2 + *len; i++) // �������� + ��������
    {
        temp += send_dat[start + i];// ��ȡУ���
    }
    send_dat[start + 2 + *len]     = temp; // 2����������
    send_dat[start + 2 + *len + 1] = temp >> 8;
}

/**
 * @brief ��ȡϵͳ����״̬
 * @param send_dat �������ݻ�����
 * @param len      ���ݳ���ָ��
 * @param start    ����д����ʼλ��
 */
static void Overall_Status(uint8_t *send_dat, uint16_t *len, uint8_t start)
{
    uint8_t i;
    *len = 32;
    send_dat[start] = *len;
    send_dat[start+1] = *len>>8;
    for(i = 0;i < *len;i++)
        send_dat[start+2+i] = g_parameters.dat[i];
}

/**
 * @brief �����豸����
 * @param send_dat �������ݻ�����
 * @param len      ���ݳ���ָ��
 * @param start    ����д����ʼλ��
 */
static void Name_Search(uint8_t *send_dat, uint16_t *len, uint8_t start)
{
    *len = 0x06;
    uint8_t i;
    const uint8_t name[6] = {'W', 'A', 'G', '1', '1', '3'};
    send_dat[start] = *len;
    send_dat[start+1] = *len>>8;
    for(i = 0; i < *len; i++)
        send_dat[start+2+i] = name[i];
}

/**
 * @brief �ɻ�ģʽ���������
 * @param g_garameters Э������ṹ��ָ��
 * @retval ���ý��
 */
static config_t cfg_airplane_mode(Agreement_T *g_garameters)
{
    config_t ret = CFG_VALID;
    // �������Ƿ���Ч
    if(g_garameters->data[0] >  RGB_MODE_LANDING        || 
       g_garameters->data[0] <= RGB_MODE_IDLE           ||
       g_garameters->data[0] == (uint8_t)rgb_get_mode() )
    {
        ret = CFG_INVALID;
        return ret;
    }
    // ����RGB��ģʽ
    rgb_set_mode((rgb_mode_t)g_garameters->data[0]);
    return ret;
}

/**
 * @brief �ɻ�ģʽ���������
 * @param g_garameters Э������ṹ��ָ��
 * @retval ���ý��
 */
static config_t cfg_led_switch(Agreement_T *g_garameters)
{
    config_t ret = CFG_VALID;// Ĭ����Ч
    // �������Ƿ���Ч
    if( 1 == g_garameters->data[0] || 
        0 == g_garameters->data[0]    )
    {
		// ����RGB��ģʽ
		g_led_buf[g_garameters->data[0]] = g_garameters->data[1];
		return ret;
    }
	
//	my_printf(&huart1, "cfg_led_switch error\n");
	ret = CFG_INVALID;
	return ret;
}
/**
 * @brief ��������ṹ������
 */
send_cmd_t send_cmd[] = 
{
    {0x01,0x01,Overall_Status},
    {0x01,0x02,Name_Search},
};

/**
 * @brief ��������ṹ������
 */
control_cmd_t control_cmd[] = 
{
    {0x02,0x01,cfg_airplane_mode},
    {0x02,0x03,   cfg_led_switch},
};

/**
 * @brief ����Э�����ݴ�������
 * @param g_garameters Э������ṹ��ָ��
 * @param comx         ͨ�Ŷ˿ں�
 */
static void Send_Analytic_function(Agreement_T *g_garameters, uint8_t comx)
{
    uint8_t i;
    uint8_t send_dat[8+RX_DATA_LEN] = {0}; // �������ݻ�����
    uint16_t len = 0;
    // 1.����ͷ��Э��
    hand_Generate(g_garameters, send_dat);
    for(i = 0; i < sizeof(send_cmd)/sizeof(send_cmd_t); i++)
    {
        // 2.�Ա���ź������
        if ((send_cmd[i].cmd_group == g_garameters->agreement_u.agreement_t.cmd_group) &&
            (send_cmd[i].cmd_num   == g_garameters->agreement_u.agreement_t.cmd_num))
        {
            // 3.��������Э��
            send_cmd[i].func(send_dat, &len, 8);
            // 4.����У��Э��
            Checksum_calculation(send_dat, &len, 8);
            
            // 5.����Э��
//          HAL_UART_Transmit(&huart1, send_dat, 10+len+2, 100);
            com_send_data(0, send_dat, 10+len+2);
        }
    }
}

/**
 * @brief �������������
 * @param g_garameters Э������ṹ��ָ��
 * @param comx         ͨ�Ŷ˿ں�
 */
static void set_command(Agreement_T *g_garameters, uint8_t comx)
{
    uint8_t i;
    for(i = 0; i < sizeof(control_cmd)/sizeof(cmd_entry_t); i++)
    {
        // 1.�Ա���ź������
        if ((control_cmd[i].cmd_group == g_garameters->agreement_u.agreement_t.cmd_group) &&
            (control_cmd[i].cmd_num   == g_garameters->agreement_u.agreement_t.cmd_num))
        {
            // 2.���ò���
            config_t ret;
            ret = control_cmd[i].func(g_garameters);
//            if( ret == CFG_VALID )
//                com_send_str(comx, "control success!\n");
//            else
//                com_send_str(comx, "control error!\n");
        }
    }
}

/**
 * @brief Э�����������
 * @param g_garameters Э������ṹ��ָ��
 * @param comx         ͨ�Ŷ˿ں�
 */
void group_analysis(Agreement_T *g_garameters, uint8_t comx)
{
    switch(g_garameters->agreement_u.agreement_t.cmd_group)
    {
        case 0x01:// �ظ�������
            Send_Analytic_function(g_garameters, comx);
        break;
        case 0x02:// ����������
            set_command(g_garameters, comx);
        break;
    }
}

/**
 * @brief Э�����ȫ�ֱ���
 */
Agreement_T  g_garameters = {0};

/**
 * @brief Э�����ݽ��������
 * @param cb   ѭ��������ָ��
 * @param comx ͨ�Ŷ˿ں�
 */
void Analytic_function(CircularBuffer_t *cb, uint8_t comx)
{
    uint16_t  index = 0; // ��������
    uint8_t   dat   = 0; // ��ʱ����
    CircularBuffer_Get(cb, &dat);
    while(dat < 0x100)
    {
		uint8_t   OK    = 1; // У���־
        switch(index)
        {
            case 65535:// ��������
                HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
                group_analysis(&g_garameters, comx);
                OK = 0;
            break;
            case 0:if(dat != 0xA5) OK = 0;break;
            case 1:if(dat != 0x5A) OK = 0;break;
            case 2:if(dat != 0x10 && dat != 0x11) OK = 0;break;
            case 3:
            case 4:
            case 5:g_garameters.agreement_u.agreement_t.cmd_group = dat;break;
            case 6:g_garameters.agreement_u.agreement_t.cmd_num = dat;break;
            case 7:if(dat != 0x00) OK = 0;break;
            case 8:g_garameters.agreement_u.agreement_t.len = dat;break;
            case 9:
                HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
                g_garameters.sum += dat;
                g_garameters.agreement_u.agreement_t.len |= (dat<<8);
                memset(g_garameters.data, 0, RX_DATA_LEN);
            break;
            default:
                g_garameters.sum += dat;
                g_garameters.data[index-10] = dat;
                if ((index-9) == g_garameters.agreement_u.agreement_t.len)
                {
                    index = 65534;
                }
            break;
        }
        if(OK == 1)
        {
            ++index;
            HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_RESET);
        }
        else if(dat == 0xA5) index = 1;
        else index = 0;
        if( R_OK != CircularBuffer_Get(cb, &dat) ) break;
    }
}
